<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Parameterized Modules
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora131.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora133.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Parameterized Modules</H2><A NAME="foncteur"></A>
<A NAME="@concepts291"></A>
<A NAME="@concepts292"></A>
Parameterized modules are to modules what functions are to base
values. Just like a function returns a new value from the values of
its parameters, a parameterized module builds a new module from the
modules given as parameters. Parameterized modules are also called
functors.<BR>
<BR>
The addition of functors to the module language increases the
opportunities for code reuse in structures.<BR>
<BR>
Functors are defined using a function-like syntax:
<A NAME="@fonctions379"></A>


<H3> Syntax </H3> <HR>


<B>functor</B> <B>(</B> <I>Name</I> <B>:</B> <I>signature</I> <B>)</B>
  -&gt; structure



<HR>

<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>Couple<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>functor</B><CODE> </CODE><TT>(</TT><CODE> </CODE>Q<CODE> </CODE><CODE>:</CODE><CODE> </CODE><B>sig</B><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><B>end</B><CODE> </CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><B>type</B><CODE> </CODE>couple<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Q.t<CODE> </CODE><CODE>*</CODE><CODE> </CODE>Q.t<CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module Couple :</CODE><BR><CODE>  functor(Q : sig type t end) -&gt; sig type couple = Q.t * Q.t end</CODE><BR>

</PRE>
<BR>
<BR>
As for functions, syntactic sugar is provided for defining and naming
a functor:


<H3> Syntax </H3> <HR>


<B>module</B> <I>Name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>(</B> <I>Name</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>:</B>
<I>signature</I> <B>)</B> <B>=</B> <I>structure</I> 



<HR>




<PRE><BR># <B>module</B><CODE> </CODE>Couple<CODE> </CODE><TT>(</TT><CODE> </CODE>Q<CODE> </CODE><CODE>:</CODE><CODE> </CODE><B>sig</B><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><B>end</B><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><B>type</B><CODE> </CODE>couple<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Q.t<CODE> </CODE><CODE>*</CODE><CODE> </CODE>Q.t<CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module Couple :</CODE><BR><CODE>  functor(Q : sig type t end) -&gt; sig type couple = Q.t * Q.t end</CODE><BR>

</PRE>
<BR>
<BR>
A functor can take several parameters:


<H3> Syntax </H3> <HR>


<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>functor</B> <B>(</B> <I>Name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>:</B> <I>signature</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>)</B>  -&gt; &nbsp;&nbsp;:</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>functor</B> <B>(</B> <I>Name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB>
<B>:</B> <I>signature</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>)</B>  -&gt; &nbsp;&nbsp;<I>structure</I></TD>
</TR></TABLE>



<HR>


The syntactic sugar for defining and naming a functor extends to
multiple-argument functors:


<H3> Syntax </H3> <HR>


<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>module</B> <I>Name</I> <B>(</B><I>Name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>:</B>
<I>signature</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>)</B> ...<B>(</B>
<I>Name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>:</B> <I>signature</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>)</B> <B>=</B></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;&nbsp;<I>structure</I></TD>
</TR></TABLE>



<HR>

<BR>
<BR>
The application of a functor to its arguments is written thus:


<H3> Syntax </H3> <HR>


<B>module</B> <I>Name</I> <B>=</B> 
<I>functor</I> <B>(</B> <I>structure</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>)</B> ...<B>(</B> <I>structure</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>)</B>



<HR>


Note that each parameter is written between parentheses. The result
of the application can be either a simple module or a partially
applied functor, depending on the number of parameters of the functor.<BR>
<BR>


<H3> Warning </H3> <HR>

There is no equivalent to functors at the level of signature: it is
not possible to build a signature by application of a ``functorial
signature'' to other signatures.


<HR>

<BR>
<BR>
A closed functor is a functor that does not reference any module
except its parameters. Such a closed functor makes its communications
with other modules entirely explicit. This provides maximal
reusability, since the modules it references are determined at
application time only. There is a strong parallel between a closed
function (without free variables) and a closed functor.<BR>
<BR>
<A NAME="toc187"></A>
<H3> Functors and Code Reuse</H3><A NAME="@fonctions380"></A>
<A NAME="@fonctions381"></A>
The Objective CAML standard library provides three modules defining
functors. Two of them take as argument a module implementing a
totally ordered data type, that is, a module with the following signature:


<PRE><BR># <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>OrderedType<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>sig</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>compare<CODE>:</CODE><CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type OrderedType = sig type t val compare : t -&gt; t -&gt; int end</CODE><BR>

</PRE>
<BR>
<BR>
Function <TT>compare</TT> takes two arguments of type <TT>t</TT>
and returns a negative integer if the first is less than the second,
zero if both are equal, and a positive integer if the first is greater
than the second. Here is an example of totally ordered type: pairs of
integers equipped with lexicographic ordering.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>OrderedIntPair<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int<CODE> </CODE><CODE>*</CODE><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>compare<CODE> </CODE><TT>(</TT>x1<CODE>,</CODE>x2<TT>)</TT><CODE> </CODE><TT>(</TT>y1<CODE>,</CODE>y2<TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>x1<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE>y1<CODE> </CODE><B>then</B><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>x1<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>y1<CODE> </CODE><B>then</B><CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>x2<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE>y2<CODE> </CODE><B>then</B><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>x2<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>y2<CODE> </CODE><B>then</B><CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module OrderedIntPair :</CODE><BR><CODE>  sig type t = int * int val compare : 'a * 'b -&gt; 'a * 'b -&gt; int end</CODE><BR>

</PRE>
<BR>
<BR>
The functor <TT>Make</TT> from module <TT>Map</TT> returns a module
that implements association tables whose keys are values of the
ordered type passed as argument. This module provides operations
similar to the operations on association lists from module
<TT>List</TT>, but using a more efficient and more complex data
structure (balanced binary trees).<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>AssocIntPair<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Map<CODE>.</CODE>Make<CODE> </CODE><TT>(</TT>OrderedIntPair<TT>)</TT><CODE> </CODE>;;<BR><CODE>module AssocIntPair :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type key = OrderedIntPair.t</CODE><BR><CODE>    and 'a t = 'a Map.Make(OrderedIntPair).t</CODE><BR><CODE>    val empty : 'a t</CODE><BR><CODE>    val add : key -&gt; 'a -&gt; 'a t -&gt; 'a t</CODE><BR><CODE>    val find : key -&gt; 'a t -&gt; 'a</CODE><BR><CODE>    val remove : key -&gt; 'a t -&gt; 'a t</CODE><BR><CODE>    val mem : key -&gt; 'a t -&gt; bool</CODE><BR><CODE>    val iter : (key -&gt; 'a -&gt; unit) -&gt; 'a t -&gt; unit</CODE><BR><CODE>    val map : ('a -&gt; 'b) -&gt; 'a t -&gt; 'b t</CODE><BR><CODE>    val fold : (key -&gt; 'a -&gt; 'b -&gt; 'b) -&gt; 'a t -&gt; 'b -&gt; 'b</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>Make</TT> functor allows to construct association tables over
any key type for which we can write a <TT>compare</TT> function.<BR>
<BR>
The standard library module <TT>Set</TT> also provides a functor named
<TT>Make</TT> taking an ordered type as argument and returning a
module implementing sets of sets of values of this type.


<PRE><BR># <B>module</B><CODE> </CODE>SetIntPair<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Set<CODE>.</CODE>Make<CODE> </CODE><TT>(</TT>OrderedIntPair<TT>)</TT><CODE> </CODE>;;<BR><CODE>module SetIntPair :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type elt = OrderedIntPair.t</CODE><BR><CODE>    and t = Set.Make(OrderedIntPair).t</CODE><BR><CODE>    val empty : t</CODE><BR><CODE>    val is_empty : t -&gt; bool</CODE><BR><CODE>    val mem : elt -&gt; t -&gt; bool</CODE><BR><CODE>    val add : elt -&gt; t -&gt; t</CODE><BR><CODE>    val singleton : elt -&gt; t</CODE><BR><CODE>    val remove : elt -&gt; t -&gt; t</CODE><BR><CODE>    val union : t -&gt; t -&gt; t</CODE><BR><CODE>    val inter : t -&gt; t -&gt; t</CODE><BR><CODE>    val diff : t -&gt; t -&gt; t</CODE><BR><CODE>    val compare : t -&gt; t -&gt; int</CODE><BR><CODE>    val equal : t -&gt; t -&gt; bool</CODE><BR><CODE>    val subset : t -&gt; t -&gt; bool</CODE><BR><CODE>    val iter : (elt -&gt; unit) -&gt; t -&gt; unit</CODE><BR><CODE>    val fold : (elt -&gt; 'a -&gt; 'a) -&gt; t -&gt; 'a -&gt; 'a</CODE><BR><CODE>    val cardinal : t -&gt; int</CODE><BR><CODE>    val elements : t -&gt; elt list</CODE><BR><CODE>    val min_elt : t -&gt; elt</CODE><BR><CODE>    val max_elt : t -&gt; elt</CODE><BR><CODE>    val choose : t -&gt; elt</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
The type <TT>SetIntPair.t</TT> is the type of sets of integer pairs,
with all the usual set operations provided in <TT>SetIntPair</TT>,
including a set comparison function <TT>SetIntPair.compare</TT>.
To illustrate the code reuse made possible by functors, we now build
sets of sets of integer pairs.


<PRE><BR># <B>module</B><CODE> </CODE>SetofSet<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Set<CODE>.</CODE>Make<CODE> </CODE><TT>(</TT>SetIntPair<TT>)</TT><CODE> </CODE>;;<BR><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>SetIntPair.singleton<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* x = { (1,2) }        *)</CODE><BR><CODE>val x : SetIntPair.t = &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>SetofSet.singleton<CODE> </CODE>SetIntPair.empty<CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE>(* y = { {} }           *)</CODE><BR><CODE>val y : SetofSet.t = &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>z<CODE> </CODE><CODE>=</CODE><CODE> </CODE>SetofSet.add<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* z = { {(1,2)} ; {} } *)</CODE><BR><CODE>val z : SetofSet.t = &lt;abstr&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>Make</TT> functor from module <TT>Hashtbl</TT> is similar to
that from the <TT>Map</TT> module, but implements (imperative) hash
tables instead of (purely functional) balanced trees. The argument to
<TT>Hashtbl.Make</TT> is slightly different: in addition to the type
of the keys for the hash table, it must provide an equality function
testing the equality of two keys (instead of a full-fledged comparison
function), plus a hash function, that is, a function associating
integers to keys.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>HashedType<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>sig</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>equal<CODE>:</CODE><CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>hash<CODE>:</CODE><CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type HashedType =</CODE><BR><CODE>  sig type t val equal : t -&gt; t -&gt; bool val hash : t -&gt; int end</CODE><BR># <B>module</B><CODE> </CODE>IntMod13<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>equal<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><CODE>=</CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>hash<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><B>mod</B><CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module IntMod13 :</CODE><BR><CODE>  sig type t = int val equal : 'a -&gt; 'a -&gt; bool val hash : int -&gt; int end</CODE><BR># <B>module</B><CODE> </CODE>TblInt<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Hashtbl<CODE>.</CODE>Make<CODE> </CODE><TT>(</TT>IntMod13<TT>)</TT><CODE> </CODE>;;<BR><CODE>module TblInt :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type key = IntMod13.t</CODE><BR><CODE>    and 'a t = 'a Hashtbl.Make(IntMod13).t</CODE><BR><CODE>    val create : int -&gt; 'a t</CODE><BR><CODE>    val clear : 'a t -&gt; unit</CODE><BR><CODE>    val add : 'a t -&gt; key -&gt; 'a -&gt; unit</CODE><BR><CODE>    val remove : 'a t -&gt; key -&gt; unit</CODE><BR><CODE>    val find : 'a t -&gt; key -&gt; 'a</CODE><BR><CODE>    val find_all : 'a t -&gt; key -&gt; 'a list</CODE><BR><CODE>    val mem : 'a t -&gt; key -&gt; bool</CODE><BR><CODE>    val iter : (key -&gt; 'a -&gt; unit) -&gt; 'a t -&gt; unit</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc188"></A>
<H3> Local Module Definitions</H3>
<A NAME="@concepts293"></A>
The Objective CAML core language allows a module to be defined locally to an
expression.


<H3> Syntax </H3> <HR>


<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>let</B> <B>module</B> <I>Name</I> = <I>structure</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;&nbsp;<B>in</B> <I>expr</I></TD>
</TR></TABLE>



<HR>


<BR>
<BR>
For instance, we can use the <TT>Set</TT> module locally to write a
sort function over integer lists, by inserting each list element into a
set and finally converting the set to the sorted list of its elements.


<PRE><BR># <B>let</B><CODE> </CODE>sort<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>module</B><CODE> </CODE>M<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>compare<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE>y<CODE> </CODE><B>then</B><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>y<CODE> </CODE><B>then</B><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>module</B><CODE> </CODE>MSet<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Set<CODE>.</CODE>Make<TT>(</TT>M<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE>MSet.elements<CODE> </CODE><TT>(</TT>List.fold_right<CODE> </CODE>MSet.add<CODE> </CODE>l<CODE> </CODE>MSet.empty<TT>)</TT><CODE> </CODE>;;<BR><CODE>val sort : int list -&gt; int list = &lt;fun&gt;</CODE><BR><BR># sort<CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;<CODE> </CODE><CODE>3</CODE><CODE> </CODE>;<CODE> </CODE><CODE>8</CODE><CODE> </CODE>;<CODE> </CODE><CODE>7</CODE><CODE> </CODE>;<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<CODE> </CODE><CODE>6</CODE><CODE> </CODE>;<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<CODE> </CODE><BR><CODE>- : int list = [1; 2; 3; 4; 5; 6; 7; 8]</CODE><BR>

</PRE>
<BR>
<BR>
Objective CAML does not allow a value to escape a <TT>let module</TT>
expression if the type of the value is not known outside the scope
of the expression.


<PRE><BR># <B>let</B><CODE> </CODE>test<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>module</B><CODE> </CODE>Foo<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>t<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>id<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>x<CODE>:</CODE>t<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>Foo.id<CODE> </CODE>;;<BR><CODE>Characters 15-101:</CODE><BR><CODE>This `let module' expression has type Foo.t -&gt; Foo.t</CODE><BR><CODE>In this type, the locally bound module name Foo escapes its scope</CODE><BR>

</PRE>
<BR>
<BR>
<HR>
<A HREF="book-ora131.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora133.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
